/*
* PhysicsMgr.h
* 
* Created February 3rd, 2012
*
*/

#pragma once

#pragma region INCLUDEs
//
#include "Box2D.h"
#include "Box3D.h"
#include "Circle2D.h"
#include "Circle3D.h"

#include <list>
using namespace std;
//
#pragma endregion


namespace Physics
{
	class PhysicsMgr
	{
	private: 
		//DATA MEMBERS...
		static PhysicsMgr *mgr;				//D001: private instance of Class for Singleton
		//add an array to hold all shapes...
		static list<Box2D> box2D;			//D002: List of Box2D
		static list<Box3D> box3D;			//D003: List of Box3D
		static list<Circle2D> circle2D;		//D004: List of Circle2D
		static list<Circle3D> circle3D;		//D005: List of Circle3D

		static int assignObjID;				//D006: Used to assign UNIQUE objID to all shapes

		//-----------------------------------------------------
		//not copyable
		PhysicsMgr(PhysicsMgr const&); 
		PhysicsMgr& operator=(PhysicsMgr const&);

#pragma region UPDATE_OBJECTs
		//
		void update_Box2D( const double time );
		void update_Box3D( const double time );
		void update_Circle2D( const double time );
		void update_Circle3D( const double time );
#pragma endregion 


#pragma region INSTANTIATION	
	protected:
		PhysicsMgr() { /*** EMPTY CONSTRUCTOR ***/ }	//C001: DEFAULT Constructor
		virtual ~PhysicsMgr();							//C004: Destructor

	public:
		static PhysicsMgr* Instance();					//C002: Create Single Instance 
		void Reset();									//C003: Clear the array stored with shapes
#pragma endregion


#pragma region ADD_OBJECT
		//
		void CreateObject(const Box2D &box);			//M003: Add a Box2D to Physics Array
		void CreateObject(const Box3D &box);			//M004: Add a Box3D to Physics Array
		void CreateObject(const Circle2D &circle);		//M005: Add a Circle2D to Physics Array
		void CreateObject(const Circle3D &circle);		//M006: Add a Circle3D to Physics Array
#pragma endregion 

		void PhysicsUpdate( const double time );		//M006: Update all physics transformation


#pragma region REMOVE_OBJECT
		bool RemoveObject(const Box2D &box);			//M007: Remove a Shape from Physics Array
		bool RemoveObject(const Box3D &box);			//M008: Remove a Box3D from Physics Array
		bool RemoveObject(const Circle2D &circle);		//M009: Remove a Circle2D from Physics Array
		bool RemoveObject(const Circle3D &circle);		//M010: Remove a Circle3D from Physics Array
		
		//Box2D
		bool RemoveLast_Box2D();						//M011: Remove Last obj from Physics array
		bool RemoveFirst_Box2D();						//M012: Remove First obj from Physics array
		//Box3D
		bool RemoveLast_Box3D();						//M011: Remove Last obj from Physics array
		bool RemoveFirst_Box3D();						//M012: Remove First obj from Physics array
		//Circle2D
		bool RemoveLast_Circle2D();						//M011: Remove Last obj from Physics array
		bool RemoveFirst_Circle2D();					//M012: Remove First obj from Physics array
		//Circle3D
		bool RemoveLast_Circle3D();						//M011: Remove Last obj from Physics array
		bool RemoveFirst_Circle3D();					//M012: Remove First obj from Physics array
#pragma endregion 


#pragma region ITERATORS
		//Box2D
		const int begin_Box2D() const;					//M013: Start Iterator
		const int end_Box2D() const;					//M014: End Iterator
		const int size_Box2D() const;					//M015: Size of Shapes List

		//Box3D
		const int begin_Box3D() const;					//M016: Start Iterator
		const int end_Box3D() const;					//M017: End Iterator
		const int size_Box3D() const;					//M018: Size of Shapes List

		//Circle2D
		const int begin_Circle2D() const;				//M019: Start Iterator
		const int end_Circle2D() const;					//M020: End Iterator
		const int size_Circle2D() const;				//M021: Size of Shapes List

		//Circle3D
		const int begin_Circle3D() const;				//M022: Start Iterator
		const int end_Circle3D() const;					//M023: End Iterator
		const int size_Circle3D() const;				//M024: Size of Shapes List
#pragma endregion


#pragma region GETTERs
		//
		Box2D getBox2D( int index ) const;
		Box3D getBox3D( int index ) const;
		Circle2D getCircle2D( int index ) const;
		Circle3D getCircle3D( int index ) const;
#pragma endregion


#pragma region SETTERs
		//
		void setBox2D( int index, const Box2D &rhs );
		void setBox3D( int index, const Box3D &rhs );
		void setCircle2D( int index, const Circle2D &rhs );
		void setCircle3D( int index, const Circle3D &rhs );
#pragma endregion
	};
} /* NAMESPACE */

